package cn.vehicle.service.impl;

import cn.vehicle.domains.bo.QueryCameraBo;
import cn.vehicle.domains.entity.CameraEntity;
import cn.vehicle.exception.VehicleAccessException;
import cn.vehicle.mapper.CameraMapper;
import cn.vehicle.service.CameraService;
import jakarta.annotation.Resource;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * 相机服务实现类
 * <p>
 * 负责相机数据的持久化操作，包括新增、更新、删除、查询及解绑等功能。
 * 该类通过调用 {@link CameraMapper} 完成数据库交互，属于 Service 层的具体实现。
 * </p>
 *
 * <p>主要职责：</p>
 * <ul>
 *   <li>封装相机表（camera）的基础增删改查逻辑；</li>
 *   <li>捕获数据库异常并转换为业务异常 {@link VehicleAccessException}；</li>
 *   <li>为业务层（Biz 层）提供数据访问支持。</li>
 * </ul>
 */
@Service
public class CameraServiceImpl implements CameraService {

    @Resource
    private CameraMapper cameraMapper;

    /**
     * 新增相机记录
     *
     * @param cameraEntity 相机实体对象
     * @throws VehicleAccessException 当相机已存在（唯一约束冲突）时抛出
     */
    @Override
    public void addCamera(CameraEntity cameraEntity) {
        try {
            // 尝试插入相机数据，若数据库存在相同主键或唯一约束冲突则捕获异常
            cameraMapper.insertCamera(cameraEntity);
        } catch (DuplicateKeyException e) {
            // 转换数据库异常为业务异常，提示“相机已存在”
            throw VehicleAccessException.DATE_EXIST.newInstance("相机已存在");
        }
    }

    /**
     * 更新相机信息
     *
     * @param updateEntity 需更新的相机实体
     * @throws VehicleAccessException 若更新失败（未匹配到记录）则抛出异常
     */
    @Override
    public void updateCamera(CameraEntity updateEntity) {
        // 执行相机更新操作，仅更新非空字段
        int i = cameraMapper.updateCameraSelective(updateEntity);
        // 若未更新到任意记录，说明数据不存在，抛出业务异常
        if (i != 1) {
            throw VehicleAccessException.DATE_NOT_EXIST.newInstance("更新相机未更新到数据");
        }
    }

    /**
     * 根据ID查询相机信息
     *
     * @param id 相机主键ID
     * @return 相机实体对象
     */
    @Override
    public CameraEntity getCameraById(Long id) {
        return cameraMapper.selectCameraById(id);
    }

    /**
     * 根据绑定关系ID查询相机列表
     *
     * @param id 被关联相机ID
     * @return 相机实体列表
     */
    @Override
    public List<CameraEntity> queryByAssociationCameraId(Long id) {
        return cameraMapper.queryByAssociationCameraId(id);
    }

    /**
     * 删除相机记录
     *
     * @param id 相机主键ID
     * @throws VehicleAccessException 若删除失败（未找到记录）则抛出异常
     */
    @Override
    public void deleteCamera(Long id) {
        // 根据主键ID执行删除操作
        int i = cameraMapper.deleteCameraById(id);
        // 删除数量不为1，说明相机不存在或已被删除
        if (i != 1) {
            throw VehicleAccessException.DATE_NOT_EXIST.newInstance("删除相机未删除到数据");
        }
    }

    /**
     * 查询相机列表
     *
     * @param queryCameraBo 查询条件封装对象
     * @return 相机实体列表
     */
    @Override
    public List<CameraEntity> selectCameraList(QueryCameraBo queryCameraBo) {
        // 执行条件查询并返回结果集
        return cameraMapper.selectCameraList(queryCameraBo);
    }

    /**
     * 解绑相机（清除关联关系）
     *
     * @param id 相机主键ID
     */
    @Override
    public void unBindCamera(Long id) {
        // 调用 Mapper 执行解绑操作，将关联字段置空
        cameraMapper.unBindCamera(id);
    }

    @Override
    public CameraEntity getCameraByIp(String ip) {
        return cameraMapper.selectCameraByIp(ip);
    }

    @Override
    public CameraEntity getCameraByCameraCode(String cameraCode) {
        return cameraMapper.getCameraByCameraCode(cameraCode);
    }
}
